from typing import List
from typing import Type
from dto.strategy_calculate_result import StrategyCalculateResult
from dto.strategy_info import StrategyInfoMetadata
from dto.strategy_stock_day import StrategyStockDay
from .das.stock_day_das import StockDateDayDas
import inspect
from dto.stock_risk_assessment import RiskAssessmentDTO
from .strategy.base_strategy import BaseStrategy
from .das.stock_assessment_das import RiskAssessmentService
from .das.stock_day_das import StockDateDayDas
import inspect
import sys


class StrategyService:
    def __init__(self):
        self.risk_service = RiskAssessmentService()
        self.stock_data_service = StockDateDayDas()

    def do_strategy_flow(self, stock_code):
        """ """
        # 拿到需要拉取的股票数据 : 默认拉取 30 天
        stock_day_num = 30
        stock_data_info = self.stock_data_service.search_by_day(
            stock_code, stock_day_num
        )

        finalResult = StrategyCalculateResult()

        # 前置处理
        preHandler = StrategyPreHandler()

        # self.execute_strategies_by_group(stock_data_info)

    def find_all_subclasses(base_class: Type) -> List[Type]:
        """
        查找所有继承自指定基类的子类
        :param base_class: 要查找子类的基类
        :return: 所有子类的列表
        """
        subclasses = []
        # 遍历当前模块内所有的类
        for name, obj in inspect.getmembers(sys.modules[__name__], inspect.isclass):
            # 确保当前类是 base_class 的子类并且不是 base_class 本身
            if issubclass(obj, base_class) and obj is not base_class:
                subclasses.append(obj)
        return subclasses

    def execute_strategies_by_group(self, trade_info: List[StrategyStockDay]):
        """
        按照 StrategyInfoMetadata 的 strategy_group 分别调用实现类
        """
        strategies = self.find_all_subclasses(BaseStrategy)
        group_mapping = {0: [], 1: []}  # 0: 风险型策略, 1: 关注型策略
        grouped_assessments = {0: [], 1: []}

        for strategy_cls in strategies:
            # 实例化策略类
            strategy_instance = strategy_cls()
            strategy_metadata = strategy_instance.strategyConfig()

            # 根据 group 分类
            group = strategy_metadata.strategy_group
            if group in group_mapping:
                group_mapping[group].append(strategy_instance)

        # 分别执行策略组
        for group, strategy_list in group_mapping.items():
            AntLogger.info(f"Executing strategies for group {group}:")
            for strategy in strategy_list:
                analyze_day_data = self.get_required_days_data(
                    trade_info, strategy_metadata
                )
                try:
                    result = strategy.analyze(analyze_day_data)
                    grouped_assessments[strategy_metadata.strategy_group].append(result)
                except Exception as e:
                    AntLogger.info(f"Error in strategy {strategy_class.__name__}: {e}")

        return grouped_assessments

    def get_required_days_data(
        trade_info_list: List[StrategyStockDay], strategy_metadata: StrategyInfoMetadata
    ) -> List[StrategyStockDay]:
        """
        根据 strategy_metadata 的分析天数，从 trade_info_list 中提取对应数量的数据
        :param trade_info_list: 股票交易数据的列表
        :param strategy_metadata: 策略的元数据对象，包含分析天数
        :return: 按照所需的天数倒序提取的数据
        """
        # 确保 trade_info_list 中有足够的数据
        if len(trade_info_list) < strategy_metadata.analysis_day:
            raise ValueError(
                f"数据不足，要求至少 {strategy_metadata.analysis_day} 天的数据，但只提供了 {len(trade_info_list)} 天的数据"
            )

        # 按倒序提取最近的分析天数的数据
        return trade_info_list[-strategy_metadata.analysis_day :]
